package Controller;

import Controller.EstandarxDLG;
import Controller.AlgoritmoGenetico;

public class MetodoPercentiles extends AlgoritmoGenetico {

	public double rho1;

	public double rho2;

	public double rho3;

	public double rho4;

	public double errorRho3;

	public double errorRho4;

	public double mediana;

	public double inter_decil;

	public double tasa_pc;

	public double factor_pc;

	public MetodoPercentiles() {
		super();
	}

	public MetodoPercentiles(EstandarxDLG padre) {
		super(padre);
	}

	protected double calcularRendimiento(double cromosoma[]) {
		double l3 = cromosoma[2];
		double l4 = cromosoma[3];

		if ((l3 * l4) < 0)
			return Double.MAX_VALUE;

		double rho3, rho4;

		rho3 = Math.pow(0.9, l4) - Math.pow(0.1, l3) + Math.pow(0.5, l3) - Math.pow(0.5, l4);
		rho3 = rho3 / (Math.pow(0.9, l3) - Math.pow(0.1, l4) + Math.pow(0.5, l4) - Math.pow(0.5, l3));

		rho4 = Math.pow(0.75, l3) - Math.pow(0.25, l4) + Math.pow(0.75, l4) - Math.pow(0.25, l3);
		rho4 = rho4 / (Math.pow(0.9, l3) - Math.pow(0.1, l4) + Math.pow(0.9, l4) - Math.pow(0.1, l3));

		double rhoe3, rhoe4;
		rhoe3 = tasa_pc;
		rhoe4 = factor_pc;

		/* Funci�n a minimizar */
		return Math.pow(rho3 - Math.abs(rhoe3), 2) + Math.pow(rho4 - rhoe4, 2);
	}

	public void ajustarLambdas(double cromosoma[]) {
		double l3, l4;

		l3 = cromosoma[2];
		l4 = cromosoma[3];

		double rho3, rho4;

		rho3 = Math.pow(0.9, l4) - Math.pow(0.1, l3) + Math.pow(0.5, l3)
				- Math.pow(0.5, l4);
		rho3 = rho3	/ (Math.pow(0.9, l3) - Math.pow(0.1, l4) + Math.pow(0.5, l4) - Math.pow(0.5, l3));

		rho4 = Math.pow(0.75, l3) - Math.pow(0.25, l4) + Math.pow(0.75, l4) - Math.pow(0.25, l3);
		rho4 = rho4 / (Math.pow(0.9, l3) - Math.pow(0.1, l4) + Math.pow(0.9, l4) - Math.pow(0.1, l3));

		double rhoe3, rhoe4;

		rhoe3 = tasa_pc;
		rhoe4 = factor_pc;

		errorRho3 = Math.abs(Math.abs(rhoe3) - Math.abs(rho3));
		errorRho4 = Math.abs(rhoe4 - rho4);

		double l2, l1;

		l2 = Math.pow(0.9, l3) - Math.pow(0.1, l4) + Math.pow(0.9, l4)
				- Math.pow(0.1, l3);
		l2 = l2 / inter_decil;

		l1 = mediana - ((Math.pow(0.5, l3) - Math.pow(0.5, l4)) / l2);

		la1 = l1;
		la2 = l2;
		la3 = l3;
		la4 = l4;
	}

	public void CalcularRhos(double muestra[]) {
		double temp = 0;
		for (int i = 0; i < muestra.length; i++) {
			for (int j = 0; j < muestra.length - 1; j++) {
				if (muestra[j] > muestra[j + 1]) {
					temp = muestra[j];
					muestra[j] = muestra[j + 1];
					muestra[j + 1] = temp;
				}
			}
		}

		int datos, valorr, valorrr_1, valorrr;

		double fraccion, asobreb, rho05, rho09, rho01, rho025, rho075, m_1, m;

		datos = muestra.length;

		fraccion = (datos + 1) * 0.5;
		valorr = (int) Math.floor(fraccion);
		asobreb = fraccion - valorr;

		valorrr = valorr;
		valorrr_1 = valorr - 1;

		if (valorrr > muestra.length - 1)
			m = 0;
		else
			m = muestra[valorr];

		if (valorrr_1 < 0)
			m_1 = 0;
		else
			m_1 = muestra[valorr - 1];

		rho05 = m_1 + (asobreb * (m - m_1));

		fraccion = (datos + 1) * 0.9;
		/*
		 * asobreb = fraccion%(int) fraccion; valorr = (int) fraccion;
		 */
		valorr = (int) Math.floor(fraccion);
		asobreb = fraccion - valorr;

		valorrr = valorr;
		valorrr_1 = valorr - 1;

		if (valorrr > muestra.length - 1)
			m = 0;
		else
			m = muestra[valorr];

		if (valorrr_1 < 0)
			m_1 = 0;
		else
			m_1 = muestra[valorr - 1];

		rho09 = m_1 + (asobreb * (m - m_1));

		fraccion = (datos + 1) * 0.1;
		valorr = (int) Math.floor(fraccion);
		asobreb = fraccion - valorr;
		valorrr = valorr;
		valorrr_1 = valorr - 1;

		if (valorrr > muestra.length - 1)
			m = 0;
		else
			m = muestra[valorr];

		if (valorrr_1 < 0)
			m_1 = 0;
		else
			m_1 = muestra[valorr - 1];

		rho01 = m_1 + (asobreb * (m - m_1));

		fraccion = (datos + 1) * 0.25;
		valorr = (int) Math.floor(fraccion);
		asobreb = fraccion - valorr;
		valorrr = valorr;
		valorrr_1 = valorr - 1;

		if (valorrr > muestra.length - 1)
			m = 0;
		else
			m = muestra[valorr];

		if (valorrr_1 < 0)
			m_1 = 0;
		else
			m_1 = muestra[valorr - 1];

		rho025 = m_1 + (asobreb * (m - m_1));

		fraccion = (datos + 1) * 0.75;
		valorr = (int) Math.floor(fraccion);
		asobreb = fraccion - valorr;
		valorrr = valorr;
		valorrr_1 = valorr - 1;

		if (valorrr > muestra.length - 1)
			m = 0;
		else
			m = muestra[valorr];

		if (valorrr_1 < 0)
			m_1 = 0;
		else
			m_1 = muestra[valorr - 1];

		rho075 = m_1 + (asobreb * (m - m_1));

		mediana = rho1 = rho05;
		inter_decil = rho2 = rho09 - rho01;
		tasa_pc = rho3 = (rho05 - rho01) / (rho09 - rho05);
		factor_pc = rho4 = (rho075 - rho025) / rho2;
	}

	protected double calcularError() {
		return 0;
	}

	public static void main(String arg[]) {
		MetodoPercentiles m = new MetodoPercentiles();

		m.mediana = 5.52999997138977;
		m.inter_decil = 2.97000002861023;
		m.tasa_pc = 1.1999997880724;
		m.factor_pc = 0.58333331326443;

		m.generaciones = 20000;
		m.poblacion = 200;
		m.probabilidadCruce = 0.5;
		m.probabilidadMutacion = 0.6;
		m.valorMax = 2;
		m.valorMin = -0.2499;
		m.errorMax = 1e-9;
		
		Thread t=new Thread(m);
		t.start();
		m.ajustarLambdas(m.mejorcromo);
		System.out.println(m.la1);
		System.out.println(m.la2);
		System.out.println(m.la3);
		System.out.println(m.la4);
	}
}
